package com.glsc.ngateway.platform.controller.easyflow;


import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.easyflow.BaseFlowForm;
import com.glsc.ngateway.platform.service.easyflow.EasyFlowMessageSender;
import com.glsc.ngateway.platform.service.easyflow.EasyFlowService;
import com.glsc.ngateway.platform.service.easyflow.dto.FlowDataDto;
import com.glsc.ngateway.platform.service.easyflow.dto.ParamDoTaskRespDto;
import com.glsc.ngateway.platform.service.easyflow.dto.WorkflowMsgDto;
import com.glsc.ngateway.platform.service.easyflow.enums.FlowConstant;
import com.glsc.ngateway.platform.utils.RequestTool;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;

/**
 * @author zhouzp
 * @date 2023/11/22
 * 产品流程处理Controller基础类
 */
@Slf4j
public class BaseProdFlowController<TYPEFORM extends BaseFlowForm> {
    @Resource
    private EasyFlowService easyFlowService;

    @Resource
    private RequestTool requestTool;

    @Resource
    private EasyFlowMessageSender easyFlowMessageSender;

    /**
     * 流程类型Id
     */
    public String getProcessDefineKey() {
        return "defaultProcessDefineKey";
    }

    @PostMapping("/createFlow")
    @ApiOperation(value = "创建流程", notes = "发起流程创建，可以设置发起至草稿")
    public PlatformResponse<ParamDoTaskRespDto> createFlow(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        log.info("准备创建流程，{}", flowDataDto);
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        ParamDoTaskRespDto createProcessRespDto = easyFlowService.createFlow(flowDataDto, requestTool.getAccountFromRequest());

        return PlatformResponse.successData(createProcessRespDto);
    }


    /**
     * 保存节点数据，但是不提交任务
     */
    @PostMapping("/saveFormData")
    @ApiOperation(value = "保存节点数据", notes = "保存节点数据")
    public PlatformResponse<ParamDoTaskRespDto> saveFormData(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        log.info("保存节点数据，{}", flowDataDto);
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        easyFlowService.saveOrUpdateForm(flowDataDto, requestTool.getAccountFromRequest());
        return PlatformResponse.successData(new ParamDoTaskRespDto());
    }

    /**
     * 审核通过
     */
    @PostMapping("/taskAuditPass")
    @ApiOperation(value = "审核通过", notes = "流程审核处理通过")
    public PlatformResponse<ParamDoTaskRespDto> taskAuditPass(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        log.info("审核任务，" + flowDataDto);
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        ParamDoTaskRespDto respDto = easyFlowService.taskAuditPass(flowDataDto, requestTool.getAccountFromRequest());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 审核驳回
     */
    @PostMapping("/taskAuditReject")
    @ApiOperation(value = "审核驳回，返回上一个节点", notes = "流程审核处理")
    public PlatformResponse<ParamDoTaskRespDto> taskAuditReject(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        log.info("驳回，返回上一个节点，" + flowDataDto);
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        ParamDoTaskRespDto respDto = easyFlowService.taskAuditReject(flowDataDto, requestTool.getAccountFromRequest());

        return PlatformResponse.successData(respDto);
    }

    @RequestMapping(method = RequestMethod.POST, value = "/return2SelectNode")
    @ApiOperation(value = "退回至指定节点", notes = "退回至指定节点")
    public PlatformResponse<ParamDoTaskRespDto> return2SelectNode(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        ParamDoTaskRespDto respDto = easyFlowService.taskAuditReject(flowDataDto, requestTool.getAccountFromRequest());
        return PlatformResponse.successData(respDto);
    }


    /**
     * 根据流程实例ID或者任务ID检索流程
     *
     * @param flowDataDto processId 流程ID
     * @param flowDataDto taskId 任务ID
     */
    @PostMapping("/findByProcessIdOrTaskId")
    @ApiOperation(value = "根据流程实例ID或者任务ID检索流程", notes = "根据流程实例ID或者任务ID检索流程状态、备注等，如提供流程实例ID则认为只读方式获取数据")
    public PlatformResponse<FlowDataDto<TYPEFORM>> findByProcessIdOrTaskId(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
        log.info("查询流程内容，" + flowDataDto);
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        FlowDataDto<TYPEFORM> respDto = easyFlowService.findByProcessIdOrTaskId(flowDataDto, requestTool.getAccountFromRequest());

        //流程查看后续事件处理，MQ异步处理 （已阅任务）
        WorkflowMsgDto msgDto = new WorkflowMsgDto();
        msgDto.setPubProdFlow(true);
        msgDto.setMsgId(String.valueOf(System.currentTimeMillis()));
        msgDto.setProcessId(flowDataDto.getProcessId());
        msgDto.setProcessDefineKey(this.getProcessDefineKey());
        msgDto.setMsgType(FlowConstant.FLOW_TASK_VIEW);
        msgDto.setOperatorAccount(requestTool.getAccountFromRequest());

        easyFlowMessageSender.sendMessage(msgDto);

        return PlatformResponse.successData(respDto);
    }

    /**
     * 退回至发起人节点
     */
//    @PostMapping("/taskAuditRecall")
//    @ApiOperation(value = "退回至发起人节点，返回起始节点", notes = "流程退回至发起人节点")
//    public PlatformResponse taskAuditRecall(@RequestBody FlowDataDto<TYPEFORM> flowDataDto) {
//        log.info("退回至发起人节点，" + flowDataDto);
//        prodFlowService.taskAuditRecall(flowDataDto, requestTool.getAccountFromRequest());
//        return PlatformResponse.successMessage("流程退回至发起人节点成功");
//    }
}
